//
// Copyright 2017 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
//    names, trademarks, service marks, or product names of the Licensor
//    and its affiliates, except as required to comply with Section 4(c) of
//    the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//

#include "pxr/pxr.h"

#include "pxr/base/tf/diagnostic.h"

#include "../integerCoding.h"

#include <cstdlib>
#include <vector>
#include <string>
#include <tuple>

PXR_NAMESPACE_USING_DIRECTIVE

int main(int argc, char** argv) {

    std::vector<uint32_t> ints {
        0, 4, 13, 15, 17, 20, 23, 26, 29, 29, 32, 29, 29,
        29, 35, 38, 29, 29, 41, 38, 29, 26, 29, 29, 32, 29, 29, 29, 29, 29, 45,
        29, 29, 29, 48, 51, 29, 54, 57, 29, 29, 60, 29, 60, 29, 63, 29, 67, 70,
        29, 29, 29, 73, 29, 29, 73, 29, 29, 76, 29, 79, 82, 85, 88, 92, 88, 96,
        99, 29, 29, 102, 29, 29, 29, 29, 29, 29, 105, 29, 29, 108, 29, 29, 29,
        29, 29, 29, 99, 29, 29, 102, 29, 29, 29, 29, 29, 29, 105, 29, 29, 108,
        29, 29, 29, 29, 29, 29, 111, 114, 117, 29, 29, 29, 29, 121, 29, 29, 124,
        29, 29, 29, 29, 127, 130, 134, 137, 29, 29, 29, 29, 141, 29, 29, 144,
        29, 29, 29, 29, 147, 130, 114, 117, 29, 29, 29, 29, 121, 29, 29, 124,
        29, 29, 29, 29, 127, 130, 134, 137, 29, 29, 29, 29, 141, 29, 29, 144,
        29, 29, 29, 29, 147, 130, 150, 153, 159, 159, 159, 159, 163, 167, 171,
        175, 175, 167, 163, 167, 171, 167, 171, 167, 167, 171, 179, 179, 183,
        167, 167, 187, 191, 191, 1707, 24580, 1707, 24580, 1707, 24580, 1707,
        24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580,
        1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707,
        24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580,
        1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707,
        24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580,
        1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707, 24580, 1707,
        24580, 2042, 24545, 2042, 2042, 24545, 2042, 1707, 24580, 2042, 24545,
        2042, 1707, 24580, 2042, 24545, 2042, 2042, 24545, 2042, 2042, 24545,
        2042, 1707, 24580, 2042, 24545, 2042, 2042, 24545, 2042, 2042, 24545,
        2042, 1707, 24580, 2042, 24545, 2042, 2042, 24545, 2042, 2042, 24545,
        2042, 1707, 24580, 2042, 24545, 2042, 2042, 24545, 2042, 1707, 24580,
        2042, 24545, 2042, 2042, 24545, 2042, 1707, 24580, 2042, 24545, 2042,
        2042, 24545, 2042, 63854, 63854, 63854, 63854, 63854, 63854, 63854,
        63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854,
        63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854,
        63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854,
        63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854, 63854,
        63854, 63854, 63854, 63854, 63854, 63854, 1750, 1750, 1750, 1750, 1763,
        0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
        39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
        57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
        75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
        93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
        109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
        123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
        137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
        151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
        165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
        179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
        193, 194, 195, 196, 197, 198, 199, 200, 436903, 436904, 436905, 436906,
        436907, 436908, 436909, 436910, 436911, 436912, 436913, 436914, 436915,
        436916, 436917, 436918, 436919, 436920, 436921, 436922, 436923, 436924,
        436925, 436926, 436927, 436928, 436929, 436930, 436931, 436932, 436933,
        436934, 436935, 436936, 436937, 436938, 436939, 436940, 436941, 436942,
        436943, 436944, 436945, 436946, 436947, 436948, 436949, 436950, 436951,
        436952, 436953, 436954, 436955, 436956, 436957, 436958, 436959, 436960,
        436961, 436962, 436963, 436964, 436965, 436966, 436967, 436968, 436969,
        436970, 436971, 436972, 436973, 436974, 436975, 436976, 436977, 436978,
        436979, 436980, 436981, 436982, 436983, 436984, 436985, 436986, 436987,
        436988, 436989, 436990, 436991, 436992, 436993, 436994, 436995, 436996,
        436997, 436998, 436999, 437000, 437001, 437002, 437003, 437004, 437005,
        437006, 437007, 437008, 437009, 437010, 437011, 437012, 437013, 437014,
        437015, 437016, 437017, 437018, 437019, 437020, 437021, 437022, 437023,
        437024, 437025, 437026, 437027, 437028, 437029, 437030, 437031, 437032,
        437033, 437034, 437035, 437036, 437037, 437038, 437039, 437040, 437041,
        437042, 437043, 437044, 437045, 437046, 437047, 437048, 437049, 437050,
        437051, 437052, 437053, 437054, 437055, 437056, 437057, 437058, 437059,
        437060, 437061, 437062, 437063, 437064, 437065, 437066, 437067, 437068,
        437069, 437070, 437071, 437072, 437073, 437074, 437075, 437076, 437077,
        437078, 437079, 437080, 437081, 437082, 437083, 437084, 437085, 437086,
        437087, 437088, 437089, 437090, 437091, 437092, 437093, 437094, 437095,
        437096, 437097, 387216, 387218, 387220, 437098, 437099, 7, 6, 11, 10, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
        6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
            };

    // Compress.
    std::unique_ptr<char[]> compressed(
        new char[Usd_IntegerCompression::GetCompressedBufferSize(ints.size())]);
    size_t compressedSize = Usd_IntegerCompression::CompressToBuffer(
        ints.data(), ints.size(), compressed.get());
    printf("Compressed %zu 32-bit ints to %zu bytes\n", ints.size(),
           compressedSize);

    // Decompress.
    std::vector<uint32_t> decoded;
    decoded.resize(ints.size());
    Usd_IntegerCompression::DecompressFromBuffer(
        compressed.get(), compressedSize, decoded.data(), ints.size());

    TF_AXIOM(decoded == ints);

    // 64-bit version
    std::vector<uint64_t> ints64;
    for (auto x: ints) {
        ints64.push_back(static_cast<int64_t>(x) * static_cast<int64_t>(x));
    }

    // Compress.
    std::unique_ptr<char[]> compressed64(
        new char[Usd_IntegerCompression64::
                 GetCompressedBufferSize(ints64.size())]);
    size_t compressedSize64 = Usd_IntegerCompression64::CompressToBuffer(
        ints64.data(), ints64.size(), compressed64.get());
    printf("Compressed %zu 64-bit ints to %zu bytes\n", ints64.size(),
           compressedSize64);

    // Decompress.
    std::vector<uint64_t> decoded64;
    decoded64.resize(ints64.size());
    Usd_IntegerCompression64::DecompressFromBuffer(
        compressed64.get(), compressedSize64, decoded64.data(), ints64.size());

    TF_AXIOM(decoded64 == ints64);

    printf("SUCCEEDED\n");
    return 0;

}
